package com.spiro.test.net.tcp.ssl.unidirectional;

import com.spiro.test.net.common.Configuration;

import javax.net.ssl.*;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.PrintWriter;
import java.security.cert.X509Certificate;
import java.util.Scanner;

/**
 * Created by tz0643 on 2016/6/17.
 */
public class SSLTcpClient {

    private SSLSocket socket = null;
    private BufferedReader reader = null;
    private PrintWriter writer = null;

    public void start(int port) throws Exception {

        // Create a trust manager that does not validate certificate chains
        TrustManager[] trustAllCerts = new TrustManager[]{
                new X509TrustManager() {
                    public java.security.cert.X509Certificate[] getAcceptedIssuers() {
                        return null;
                    }

                    public void checkClientTrusted(X509Certificate[] certs, String authType) {
                    }

                    public void checkServerTrusted(X509Certificate[] certs, String authType) {
                    }
                }
        };

        SSLContext sslContext = SSLContext.getInstance("TLSv1");
        sslContext.init(null, trustAllCerts, null);

        try {
            SSLSocketFactory factory = sslContext.getSocketFactory();
            socket = (SSLSocket) factory.createSocket("192.168.10.188", port);
            System.out.println("Connected, port -> " + port);
        } catch (IOException e) {
            throw e;
        }

        try {
            reader = new BufferedReader(new InputStreamReader(this.socket.getInputStream()));
            Thread t = new Thread(new TcpReader(reader));
            t.setDaemon(true);
            t.start();

            writer = new PrintWriter(this.socket.getOutputStream());

            Scanner scanner = new Scanner(System.in);

            while (true) {
                System.out.println("input -> ");
                String input = scanner.next();
                writer.println(input);
                writer.flush();
            }
        } catch (IOException e) {
            throw e;
        } finally {
            if (reader != null) {
                try {
                    reader.close();
                } catch (IOException e) {
                }
            }
            if (writer != null) {
                writer.close();
            }

            if (this.socket != null) {
                try {
                    this.socket.close();
                } catch (IOException e) {
                }
            }
        }
    }

    public class TcpReader implements Runnable {

        private BufferedReader reader = null;

        public TcpReader(BufferedReader reader) {
            this.reader = reader;
        }

        @Override
        public void run() {
            String returnLine = null;

            while (true) {
                try {
                    returnLine = reader.readLine();
                    System.out.println(returnLine);
                } catch (IOException e) {
                    e.printStackTrace();
                    break;
                }
            }
        }
    }

    public static void main(String[] args) {

        Configuration conf = Configuration.getInstance();

        try {
            conf.init();
        } catch (IOException e) {
            e.printStackTrace();
            System.exit(-1);
        }

        SSLTcpClient tcpClient = new SSLTcpClient();
        try {
            tcpClient.start(9000);
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
}
